home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / perl5 / RPC / XML / Client.pm next >
Encoding:
Perl POD Document  |  2008-04-10  |  26.9 KB  |  780 lines

  1. ###############################################################################
  2. #
  3. # This file copyright (c) 2001-2008 Randy J. Ray, all rights reserved
  4. #
  5. # See "LICENSE" in the documentation for licensing and redistribution terms.
  6. #
  7. ###############################################################################
  8. #
  9. #   $Id: Client.pm 343 2008-04-09 09:54:36Z rjray $
  10. #
  11. #   Description:    This class implements an RPC::XML client, using LWP to
  12. #                   manage the underlying communication protocols. It relies
  13. #                   on the RPC::XML transaction core for data management.
  14. #
  15. #   Functions:      new
  16. #                   send_request
  17. #                   simple_request
  18. #                   uri
  19. #                   useragent
  20. #                   request
  21. #
  22. #   Libraries:      LWP::UserAgent
  23. #                   HTTP::Request
  24. #                   URI
  25. #                   RPC::XML
  26. #
  27. #   Global Consts:  $VERSION
  28. #
  29. ###############################################################################
  30.  
  31. package RPC::XML::Client;
  32.  
  33. use 5.005;
  34. use strict;
  35. use vars qw($VERSION);
  36. use subs qw(new simple_request send_request uri useragent request
  37.             fault_handler error_handler combined_handler);
  38.  
  39. require LWP::UserAgent;
  40. require HTTP::Request;
  41. require URI;
  42.  
  43. use RPC::XML 'bytelength';
  44. require RPC::XML::Parser;
  45.  
  46. $VERSION = '1.24';
  47.  
  48. ###############################################################################
  49. #
  50. #   Sub Name:       new
  51. #
  52. #   Description:    Create a LWP::UA instance and add some extra material
  53. #                   specific to our purposes.
  54. #
  55. #   Arguments:      NAME      IN/OUT  TYPE      DESCRIPTION
  56. #                   $class    in      scalar    Class to bless into
  57. #                   $location in      scalar    URI path for requests to go to
  58. #                   %attrs    in      hash      Extra info
  59. #
  60. #   Globals:        $VERSION
  61. #
  62. #   Returns:        Success:    object reference
  63. #                   Failure:    error string
  64. #
  65. ###############################################################################
  66. sub new
  67. {
  68.     my $class = shift;
  69.     my $location = shift;
  70.     my %attrs = @_;
  71.  
  72.     $class = ref($class) || $class;
  73.     return "${class}::new: Missing location argument" unless $location;
  74.  
  75.     my ($self, $UA, $REQ, $PARSER);
  76.  
  77.     # Start by getting the LWP::UA object
  78.     $UA = LWP::UserAgent->new((exists $attrs{useragent}) ?
  79.                               @{$attrs{useragent}} : ()) or
  80.         return "${class}::new: Unable to get LWP::UserAgent object";
  81.     $UA->agent(sprintf("%s/%s %s", $class, $VERSION, $UA->agent));
  82.     $self->{__useragent} = $UA;
  83.     delete $attrs{useragent};
  84.  
  85.     # Next get the request object for later use
  86.     $REQ = HTTP::Request->new(POST => $location) or
  87.         return "${class}::new: Unable to get HTTP::Request object";
  88.     $self->{__request} = $REQ;
  89.     $REQ->header(Content_Type => 'text/xml');
  90.     $REQ->protocol('HTTP/1.0');
  91.  
  92.     # Check for compression support
  93.     $self->{__compress} = '';
  94.     eval "require Compress::Zlib";
  95.     $self->{__compress} = $@ ? '' : 'deflate';
  96.     # It looks wasteful to keep using the hash key, but it makes it easier
  97.     # to change the string in just one place (above) if I have to.
  98.     $REQ->header(Accept_Encoding => $self->{__compress})
  99.         if $self->{__compress};
  100.     $self->{__compress_thresh} = $attrs{compress_thresh} || 4096;
  101.     $self->{__compress_re} = qr/$self->{__compress}/;
  102.     # They can change this value with a method
  103.     $self->{__compress_requests} = 0;
  104.     delete $attrs{compress_thresh};
  105.  
  106.     # Parameters to control the point at which messages are shunted to temp
  107.     # files due to size, and where to home the temp files. Start with a size
  108.     # threshhold of 1Meg and no specific dir (which will fall-through to the
  109.     # tmpdir() method of File::Spec).
  110.     $self->{__message_file_thresh} = $attrs{message_file_thresh} || 1048576;
  111.     $self->{__message_temp_dir}    = $attrs{message_temp_dir}    || '';
  112.     delete @attrs{qw(message_file_thresh message_temp_dir)};
  113.  
  114.     # Note and preserve any error or fault handlers. Check the combo-handler
  115.     # first, as it is superceded by anything more specific.
  116.     if (ref $attrs{combined_handler})
  117.     {
  118.         $self->{__error_cb} = $attrs{combined_handler};
  119.         $self->{__fault_cb} = $attrs{combined_handler};
  120.         delete $attrs{combined_handler};
  121.     }
  122.     if (ref $attrs{fault_handler})
  123.     {
  124.         $self->{__fault_cb} = $attrs{fault_handler};
  125.         delete $attrs{fault_handler};
  126.     }
  127.     if (ref $attrs{error_handler})
  128.     {
  129.         $self->{__error_cb} = $attrs{error_handler};
  130.         delete $attrs{error_handler};
  131.     }
  132.  
  133.     # Get the RPC::XML::Parser instance
  134.     $self->{__parser} = RPC::XML::Parser->new($attrs{parser} ?
  135.                                               @{$attrs{parser}} : ()) or
  136.         return "${class}::new: Unable to get RPC::XML::Parser object";
  137.     delete $attrs{parser};
  138.  
  139.     # Now preserve any remaining attributes passed in
  140.     $self->{$_} = $attrs{$_} for (keys %attrs);
  141.  
  142.     bless $self, $class;
  143. }
  144.  
  145. ###############################################################################
  146. #
  147. #   Sub Name:       simple_request
  148. #
  149. #   Description:    Simplify the request process by both allowing for direct
  150. #                   data on the incoming side, and for returning a native
  151. #                   value rather than an object reference.
  152. #
  153. #   Arguments:      NAME      IN/OUT  TYPE      DESCRIPTION
  154. #                   $self     in      ref       Class instance
  155. #                   @args     in      list      Various args -- see comments
  156. #
  157. #   Globals:        $RPC::XML::ERROR
  158. #
  159. #   Returns:        Success:    value
  160. #                   Failure:    undef, error in $RPC::XML::ERROR
  161. #
  162. ###############################################################################
  163. sub simple_request
  164. {
  165.     my ($self, @args) = @_;
  166.  
  167.     my ($return, $value);
  168.  
  169.     $RPC::XML::ERROR = '';
  170.  
  171.     $return = $self->send_request(@args);
  172.     unless (ref $return)
  173.     {
  174.         $RPC::XML::ERROR = ref($self) . "::simple_request: $return";
  175.         return undef;
  176.     }
  177.     $return->value;
  178. }
  179.  
  180. ###############################################################################
  181. #
  182. #   Sub Name:       send_request
  183. #
  184. #   Description:    Take a RPC::XML::request object, dispatch a request, and
  185. #                   parse the response. The return value should be a
  186. #                   RPC::XML::response object, or an error string.
  187. #
  188. #   Arguments:      NAME      IN/OUT  TYPE      DESCRIPTION
  189. #                   $self     in      ref       Class instance
  190. #                   $req      in      ref       RPC::XML::request object
  191. #
  192. #   Returns:        Success:    RPC::XML::response object instance
  193. #                   Failure:    error string
  194. #
  195. ###############################################################################
  196. sub send_request
  197. {
  198.     my ($self, $req, @args) = @_;
  199.  
  200.     my ($me, $message, $response, $reqclone, $content, $can_compress, $value,
  201.         $do_compress, $req_fh, $tmpfile, $com_engine);
  202.  
  203.     $me = ref($self) . '::send_request';
  204.  
  205.     if (! UNIVERSAL::isa($req, 'RPC::XML::request'))
  206.     {
  207.         # Assume that $req is the name of the routine to be called
  208.         $req = RPC::XML::request->new($req, @args);
  209.         return "$me: Error creating RPC::XML::request object: $RPC::XML::ERROR"
  210.             unless ($req); # $RPC::XML::ERROR is already set
  211.     }
  212.  
  213.     # Start by setting up the request-clone for using in this instance
  214.     $reqclone = $self->request->clone;
  215.     $reqclone->header(Host => URI->new($reqclone->uri)->host);
  216.     $can_compress = $self->compress; # Avoid making 4+ calls to the method
  217.     if ($self->compress_requests and $can_compress and
  218.         $req->length >= $self->compress_thresh)
  219.     {
  220.         # If this is a candidate for compression, set a flag and note it
  221.         # in the Content-encoding header.
  222.         $do_compress = 1;
  223.         $reqclone->content_encoding($can_compress);
  224.     }
  225.  
  226.     # Next step, determine our content's disposition. If it is above the
  227.     # threshhold for a requested file cut-off, send it to a temp file and use
  228.     # a closure on the request object to manage content.
  229.     if ($self->message_file_thresh and
  230.         $self->message_file_thresh <= $req->length)
  231.     {
  232.         require File::Spec;
  233.         require Symbol;
  234.         # Start by creating a temp-file
  235.         $tmpfile = $self->message_temp_dir || File::Spec->tmpdir;
  236.         ($tmpfile = File::Spec->catfile($tmpfile, __PACKAGE__ . $$ . time)) =~
  237.             s/::/-/g; # Colons in filenames bad on some systems!
  238.         $req_fh = Symbol::gensym();
  239.         return "$me: Error opening $tmpfile: $!"
  240.             unless (open($req_fh, "+> $tmpfile"));
  241.         unlink $tmpfile;
  242.         # Make it auto-flush
  243.         my $old_fh = select($req_fh); $| = 1; select($old_fh);
  244.  
  245.         # Now that we have it, spool the request to it. This is a little
  246.         # hairy, since we still have to allow for compression. And though the
  247.         # request could theoretically be HUGE, in order to compress we have to
  248.         # write it to a second temp-file first, so that we can compress it
  249.         # into the primary handle.
  250.         if ($do_compress && ($req->length >= $self->compress_thresh))
  251.         {
  252.             my $fh2 = Symbol::gensym();
  253.             $tmpfile .= '-2';
  254.             return "$me: Error opening $tmpfile: $!"
  255.                 unless (open($fh2, "+> $tmpfile"));
  256.             unlink $tmpfile;
  257.             # Make it auto-flush
  258.             $old_fh = select($fh2); $| = 1; select($old_fh);
  259.  
  260.             # Write the request to the second FH
  261.             $req->serialize($fh2);
  262.             seek($fh2, 0, 0);
  263.  
  264.             # Spin up the compression engine
  265.             $com_engine = Compress::Zlib::deflateInit();
  266.             return "$me: Unable to initialize the Compress::Zlib engine"
  267.                 unless $com_engine;
  268.  
  269.             # Spool from the second FH through the compression engine, into
  270.             # the intended FH.
  271.             my $buf = '';
  272.             my $out;
  273.             while (read($fh2, $buf, 4096))
  274.             {
  275.                 $out = $com_engine->deflate(\$buf);
  276.                 return "$me: Compression failure in deflate()"
  277.                     unless defined $out;
  278.                 print $req_fh $out;
  279.             }
  280.             # Make sure we have all that's left
  281.             $out = $com_engine->flush;
  282.             return "$me: Compression flush failure in deflate()"
  283.                 unless defined $out;
  284.             print $req_fh $out;
  285.  
  286.             # Close the secondary FH. Rewinding the primary is done later.
  287.             close($fh2);
  288.         }
  289.         else
  290.         {
  291.             $req->serialize($req_fh);
  292.         }
  293.         seek($req_fh, 0, 0);
  294.  
  295.         $reqclone->content_length(-s $req_fh);
  296.         $reqclone->content(sub {
  297.                                my $b = '';
  298.                                return undef
  299.                                    unless defined(read($req_fh, $b, 4096));
  300.                                $b;
  301.                            });
  302.     }
  303.     else
  304.     {
  305.         # Treat the content strictly in-memory
  306.         $content = $req->as_string;
  307.         $content = Compress::Zlib::compress($content) if $do_compress;
  308.         $reqclone->content($content);
  309.         $reqclone->content_length(bytelength($content));
  310.     }
  311.  
  312.     # Content used to be handled as an in-memory string. Now, to avoid eating
  313.     # up huge chunks due to potentially-massive messages (thanks Tellme), we
  314.     # parse incrementally with the XML::Parser::ExpatNB class. What's more,
  315.     # to use the callback-form of request(), we can't get just the headers
  316.     # first. We have to check things like compression and such on the fly.
  317.     my $compression;
  318.     my $parser = $self->parser->parse(); # Gets the ExpatNB object
  319.     my $cb = sub {
  320.         my ($data, $resp) = @_;
  321.  
  322.         unless (defined $compression)
  323.         {
  324.             $compression =
  325.                 (($resp->content_encoding || '') =~
  326.                  $self->compress_re) ? 1 : 0;
  327.             die "$me: Compressed content encoding not supported"
  328.                 if ($compression and (! $can_compress));
  329.             if ($compression)
  330.             {
  331.                 die "$me: Unable to initialize de-compression engine"
  332.                     unless ($com_engine = Compress::Zlib::inflateInit());
  333.             }
  334.         }
  335.  
  336.         if ($compression)
  337.         {
  338.             my $error;
  339.             die "$me: Error in inflate() expanding data: $error"
  340.                 unless (($data, $error) = $com_engine->inflate($data));
  341.         }
  342.  
  343.         $parser->parse_more($data);
  344.         1;
  345.     };
  346.  
  347.     $response = $self->useragent->request($reqclone, $cb);
  348.     if ($message = $response->headers->header('X-Died'))
  349.     {
  350.         # One of the die's was triggered
  351.         return (ref($self->error_handler) eq 'CODE') ?
  352.             $self->error_handler->($message) : $message;
  353.     }
  354.     unless ($response->is_success)
  355.     {
  356.         $message =  "$me: HTTP server error: " . $response->message;
  357.         return (ref($self->error_handler) eq 'CODE') ?
  358.             $self->error_handler->($message) : $message;
  359.     }
  360.  
  361.     # Whee. No errors from the callback or the server. Finalize the parsing
  362.     # process.
  363.     eval { $value = $parser->parse_done(); };
  364.     if ($@)
  365.     {
  366.         # One of the die's was triggered
  367.         return (ref($self->error_handler) eq 'CODE') ?
  368.             $self->error_handler->($@) : $@;
  369.     }
  370.  
  371.     # Check if there is a callback to be invoked in the case of
  372.     # errors or faults
  373.     if (! ref($value))
  374.     {
  375.         $message =  "$me: parse-level error: $value";
  376.         return (ref($self->error_handler) eq 'CODE') ?
  377.             $self->error_handler->($message) : $message;
  378.     }
  379.     elsif ($value->is_fault)
  380.     {
  381.         return (ref($self->fault_handler) eq 'CODE') ?
  382.             $self->fault_handler->($value->value) : $value->value;
  383.     }
  384.  
  385.     $value->value;
  386. }
  387.  
  388. ###############################################################################
  389. #
  390. #   Sub Name:       uri
  391. #
  392. #   Description:    Get or set the URI portion of the request
  393. #
  394. #   Arguments:      NAME      IN/OUT  TYPE      DESCRIPTION
  395. #                   $self     in      ref       Object of this class
  396. #                   $uri      in      scalar    New URI, if passed
  397. #
  398. #   Returns:        Current URI, undef if trying to set an invalid URI
  399. #
  400. ###############################################################################
  401. sub uri
  402. {
  403.     my $self = shift;
  404.     $self->request->uri(@_);
  405. }
  406.  
  407. ###############################################################################
  408. #
  409. #   Sub Name:       credentials
  410. #
  411. #   Description:    Set basic-auth credentials on the underlying user-agent
  412. #                   object
  413. #
  414. #   Arguments:      NAME      IN/OUT  TYPE      DESCRIPTION
  415. #                   $self     in      ref       Object of this class
  416. #                   $realm    in      scalar    Realm to authenticate for
  417. #                   $user     in      scalar    User name to authenticate
  418. #                   $pass     in      scalar    Password for $user
  419. #
  420. #   Returns:        $self
  421. #
  422. ###############################################################################
  423. sub credentials
  424. {
  425.     my ($self, $realm, $user, $pass) = @_;
  426.  
  427.     my $uri = URI->new($self->uri);
  428.     $self->useragent->credentials($uri->host_port, $realm, $user, $pass);
  429.     $self;
  430. }
  431.  
  432. # Immutable accessor methods
  433. BEGIN
  434. {
  435.     no strict 'refs';
  436.  
  437.     for my $method (qw(useragent request compress_re compress parser))
  438.     {
  439.         *$method = sub { shift->{"__$method"} }
  440.     }
  441. }
  442.  
  443. # Fetch/set the compression threshhold
  444. sub compress_thresh
  445. {
  446.     my $self = shift;
  447.     my $set = shift || 0;
  448.  
  449.     my $old = $self->{__compress_thresh};
  450.     $self->{__compress_thresh} = $set if ($set);
  451.  
  452.     $old;
  453. }
  454.  
  455. # This doesn't actually *get* the original value, it only sets the value
  456. sub compress_requests
  457. {
  458.     my $self = shift;
  459.  
  460.     return $self->{__compress_requests} unless @_;
  461.  
  462.     $self->{__compress_requests} = $_[0] ? 1 : 0;
  463. }
  464.  
  465. # These are get/set accessors for the fault-handler, error-handler and the
  466. # combined fault/error handler.
  467. sub fault_handler
  468. {
  469.     my ($self, $newval) = @_;
  470.  
  471.     my $val = $self->{__fault_cb};
  472.     $self->{__fault_cb} = $newval if ($newval and ref($newval));
  473.     # Special: an explicit undef is used to clear the callback
  474.     $self->{__fault_cb} = undef if (@_ == 2 and (! defined $newval));
  475.  
  476.     $val;
  477. }
  478. sub error_handler
  479. {
  480.     my ($self, $newval) = @_;
  481.  
  482.     my $val = $self->{__error_cb};
  483.     $self->{__error_cb} = $newval if ($newval and ref($newval));
  484.     # Special: an explicit undef is used to clear the callback
  485.     $self->{__error_cb} = undef if (@_ == 2 and (! defined $newval));
  486.  
  487.     $val;
  488. }
  489. sub combined_handler
  490. {
  491.     my ($self, $newval) = @_;
  492.  
  493.     ($self->fault_handler($newval), $self->error_handler($newval));
  494. }
  495.  
  496. # Control whether, and at what point, messages are considered too large to
  497. # handle in-memory.
  498. sub message_file_thresh
  499. {
  500.     my $self = shift;
  501.  
  502.     return $self->{__message_file_thresh} unless @_;
  503.  
  504.     $self->{__message_file_thresh} = shift;
  505. }
  506.  
  507. sub message_temp_dir
  508. {
  509.     my $self = shift;
  510.  
  511.     return $self->{__message_temp_dir} unless @_;
  512.  
  513.     $self->{__message_temp_dir} = shift;
  514. }
  515.  
  516. 1;
  517.  
  518. __END__
  519.  
  520. =pod
  521.  
  522. =head1 NAME
  523.  
  524. RPC::XML::Client - An XML-RPC client class
  525.  
  526. =head1 SYNOPSIS
  527.  
  528.     require RPC::XML;
  529.     require RPC::XML::Client;
  530.  
  531.     $cli = RPC::XML::Client->new('http://www.localhost.net/RPCSERV');
  532.     $resp = $cli->send_request('system.listMethods');
  533.  
  534.     print ref $resp ? join(', ', @{$resp->value}) : "Error: $resp";
  535.  
  536. =head1 DESCRIPTION
  537.  
  538. This is an XML-RPC client built upon the B<RPC::XML> data classes, and using
  539. B<LWP::UserAgent> and B<HTTP::Request> for the communication layer. This
  540. client supports the full XML-RPC specification.
  541.  
  542. =head1 METHODS
  543.  
  544. The following methods are available:
  545.  
  546. =over 4
  547.  
  548. =item new (URI [, ARGS])
  549.  
  550. Creates a new client object that will route its requests to the URL provided.
  551. The constructor creates a B<HTTP::Request> object and a B<LWP::UserAgent>
  552. object, which are stored on the client object. When requests are made, these
  553. objects are ready to go, with the headers set appropriately. The return value
  554. of this method is a reference to the new object. The C<URI> argument may be a
  555. string or an object from the B<URI> class from CPAN.
  556.  
  557. Any additional arguments are treated as key-value pairs. Most are attached to
  558. the object itself without change. The following are recognized by C<new> and
  559. treated specially:
  560.  
  561. =over 4
  562.  
  563. =item parser
  564.  
  565. If this parameter is passed, the value following it is expected to be an
  566. array reference. The contents of that array are passed to the B<new> method
  567. of the B<RPC::XML::Parser> object that the client object caches for its use.
  568. See the B<RPC::XML::Parser> manual page for a list of recognized parameters
  569. to the constructor.
  570.  
  571. =item useragent
  572.  
  573. This is similar to the C<parser> argument above, and also expects an array
  574. reference to follow it. The contents are passed to the constructor of the
  575. B<LWP::UserAgent> class when creating that component of the client object.
  576. See the manual page for B<LWP::UserAgent> for supported values.
  577.  
  578. =item error_handler
  579.  
  580. If passed, the value must be a code reference that will be invoked when a
  581. request results in a transport-level error. The closure will receive a
  582. single argument, the text of the error message from the failed communication
  583. attempt. It is expected to return a single value (assuming it returns at all).
  584.  
  585. =item fault_handler
  586.  
  587. If passed, the value must be a code reference. This one is invoked when a
  588. request results in a fault response from the server. The closure will receive
  589. a single argument, a B<RPC::XML::fault> instance that can be used to retrieve
  590. the code and text-string of the fault. It is expected to return a single
  591. value (if it returns at all).
  592.  
  593. =item combined_handler
  594.  
  595. If this parameter is specified, it too must have a code reference as a value.
  596. It is installed as the handler for both faults and errors. Should either of
  597. the other parameters be passed in addition to this one, they will take
  598. precedence over this (more-specific wins out over less). As a combined
  599. handler, the closure will get a string (non-reference) in cases of errors, and
  600. an instance of B<RPC::XML::fault> in cases of faults. This allows the
  601. developer to install a simple default handler, while later providing a more
  602. specific one by means of the methods listed below.
  603.  
  604. =item message_file_thresh
  605.  
  606. If this key is passed, the value associated with it is assumed to be a
  607. numerical limit to the size of in-memory messages. Any out-bound request that
  608. would be larger than this when stringified is instead written to an anonynous
  609. temporary file, and spooled from there instead. This is useful for cases in
  610. which the request includes B<RPC::XML::base64> objects that are themselves
  611. spooled from file-handles. This test is independent of compression, so even
  612. if compression of a request would drop it below this threshhold, it will be
  613. spooled anyway. The file itself is unlinked after the file-handle is created,
  614. so once it is freed the disk space is immediately freed.
  615.  
  616. =item message_temp_dir
  617.  
  618. If a message is to be spooled to a temporary file, this key can define a
  619. specific directory in which to open those files. If this is not given, then
  620. the C<tmpdir> method from the B<File::Spec> package is used, instead.
  621.  
  622. =back
  623.  
  624. See the section on the effects of callbacks on return values, below.
  625.  
  626. =item uri ([URI])
  627.  
  628. Returns the B<URI> that the invoking object is set to communicate with for
  629. requests. If a string or C<URI> class object is passed as an argument, then
  630. the URI is set to the new value. In either case, the pre-existing value is
  631. returned.
  632.  
  633. =item useragent
  634.  
  635. Returns the B<LWP::UserAgent> object instance stored on the client object.
  636. It is not possible to assign a new such object, though direct access to it
  637. should allow for any header modifications or other needed operations.
  638.  
  639. =item request
  640.  
  641. Returns the B<HTTP::Request> object. As with the above, it is not allowed to
  642. assign a new object, but access to this value should allow for any needed
  643. operations.
  644.  
  645. =item simple_request (ARGS)
  646.  
  647. This is a somewhat friendlier wrapper around the next routine (C<send_request>)
  648. that returns Perl-level data rather than an object reference. The arguments may
  649. be the same as one would pass to the B<RPC::XML::request> constructor, or there
  650. may be a single request object as an argument. The return value will be a
  651. native Perl value. If the return value is C<undef>, an error has occurred and
  652. C<simple_request> has placed the error message in the global variable
  653. C<B<$RPC::XML::ERROR>>.
  654.  
  655. =item send_request (ARGS)
  656.  
  657. Sends a request to the server and attempts to parse the returned data. The
  658. argument may be an object of the B<RPC::XML::request> class, or it may be the
  659. arguments to the constructor for the request class. The return value will be
  660. either an error string or a data-type object. If the error encountered was a
  661. run-time error within the RPC request itself, then the call will return a
  662. C<RPC::XML::fault> value rather than an error string.
  663.  
  664. If the return value from C<send_request> is not a reference, then it can only
  665. mean an error on the client-side (a local problem with the arguments and/or
  666. syntax, or a transport problem). All data-type classes now support a method
  667. called C<is_fault> that may be easily used to determine if the "successful"
  668. return value is actually a C<RPC::XML::fault> without the need to use
  669. C<UNIVERSAL::ISA>.
  670.  
  671. =item error_handler ([CODEREF])
  672.  
  673. =item fault_handler ([CODEREF])
  674.  
  675. =item combined_handler ([CODEREF])
  676.  
  677. These accessor methods get (and possibly set, if CODEREF is passed) the
  678. specified callback/handler. The return value is always the current handler,
  679. even when setting a new one (allowing for later restoration, if desired).
  680.  
  681. =item credentials (REALM, USERNAME, PASSWORD)
  682.  
  683. This sets the username and password for a given authentication realm at the
  684. location associated with the current request URL. Needed if the RPC location
  685. is protected by Basic Authentication. Note that changing the target URL of the
  686. client object to a different (protected) location would require calling this
  687. with new credentials for the new realm (even if the value of C<$realm> is
  688. identical at both locations).
  689.  
  690. =item message_file_thresh
  691.  
  692. =item message_temp_dir
  693.  
  694. These methods may be used to retrieve or alter the values of the given keys
  695. as defined earlier for the C<new> method.
  696.  
  697. =back
  698.  
  699. =head2 Support for Content Compression
  700.  
  701. The B<RPC::XML::Server> class supports compression of requests and responses
  702. via the B<Compress::Zlib> module available from CPAN. Accordingly, this class
  703. also supports compression. The methods used for communicating compression
  704. support should be compatible with the server and client classes from the
  705. B<XMLRPC::Lite> class that is a part of the B<SOAP::Lite> package (also
  706. available from CPAN).
  707.  
  708. Compression support is enabled (or not) behind the scenes; if the Perl
  709. installation has B<Compress::Zlib>, then B<RPC::XML::Client> can deal with
  710. compressed responses. However, since outgoing messages are sent before a
  711. client generally has the chance to see if a server supports compression, these
  712. are not compressed by default.
  713.  
  714. =over 4
  715.  
  716. =item compress_requests(BOOL)
  717.  
  718. If a client is communicating with a server that is known to support compressed
  719. messages, this method can be used to tell the client object to compress any
  720. outgoing messages that are longer than the threshhold setting in bytes.
  721.  
  722. =item compress_thresh([MIN_LIMIT])
  723.  
  724. With no arguments, returns the current compression threshhold; messages
  725. smaller than this number of bytes will not be compressed, regardless of the
  726. above method setting. If a number is passed, this is set to the new
  727. lower-limit. The default value is 4096 (4k).
  728.  
  729. =back
  730.  
  731. =head2 Callbacks and Return Values
  732.  
  733. If a callback is installed for errors or faults, it will be called before
  734. either of C<send_request> or C<simple_request> return. If the callback calls
  735. B<die> or otherwise interrupts execution, then there is no need to worry about
  736. the effect on return values. Otherwise, the return value of the callback
  737. becomes the return value of the original method (C<send_request> or
  738. C<simple_request>). Thus, all callbacks are expected, if they return at all,
  739. to return exactly one value. It is recommended that any callback return values
  740. conform to the expected return values. That is, an error callback would
  741. return a string, a fault callback would return the fault object.
  742.  
  743. =head1 DIAGNOSTICS
  744.  
  745. All methods return some type of reference on success, or an error string on
  746. failure. Non-reference return values should always be interpreted as errors,
  747. except in the case of C<simple_request>.
  748.  
  749. =head1 CAVEATS
  750.  
  751. This began as a reference implementation in which clarity of process and
  752. readability of the code took precedence over general efficiency. It is now
  753. being maintained as production code, but may still have parts that could be
  754. written more efficiently.
  755.  
  756. =head1 CREDITS
  757.  
  758. The B<XML-RPC> standard is Copyright (c) 1998-2001, UserLand Software, Inc.
  759. See <http://www.xmlrpc.com> for more information about the B<XML-RPC>
  760. specification.
  761.  
  762. =head1 LICENSE
  763.  
  764. This module and the code within are released under the terms of the Artistic
  765. License 2.0
  766. (http://www.opensource.org/licenses/artistic-license-2.0.php). This code may
  767. be redistributed under either the Artistic License or the GNU Lesser General
  768. Public License (LGPL) version 2.1
  769. (http://www.opensource.org/licenses/lgpl-license.php).
  770.  
  771. =head1 SEE ALSO
  772.  
  773. L<RPC::XML>, L<RPC::XML::Server>
  774.  
  775. =head1 AUTHOR
  776.  
  777. Randy J. Ray <rjray@blackperl.com>
  778.  
  779. =cut
  780.